﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Common.Extensions
{
	public static class EnumerableExtensions
	{
		public static Boolean IsNullOrEmpty<T>(this IEnumerable<T> coll)
		{
			return coll == null || coll.Count() == 0;
		}

		public static IEnumerable<TRes> Select<TSource, TRes>(this IList<TSource> items, System.Func<TSource, Int32, Boolean, TRes> map)
		{
			if (!items.IsNullOrEmpty())
			{
				var lastIndex = items.Count - 1;
				for (int i = 0; i < items.Count; i++)
				{
					yield return map(items[i], i, i == lastIndex);
				}
			}
		}

		public static Boolean IsAvailableIndex<T>(this IEnumerable<T> mas, Int32 index)
		{
			if (mas.IsNullOrEmpty())
				return false;
			return index >= 0 && index < mas.Count();
		}
		public static T GetSafe<T>(this IList<T> mas, Int32 index, T def)
		{
			return mas.IsAvailableIndex(index) ? mas[index] : def;
		}

        public static TRes With<T, TRes>(this T o, Func<T, TRes> evaluator)
        {
            return IsNull(o) ? default(TRes) : evaluator(o);
        }

        public static TResult Return<TInput, TResult>(this TInput o, Func<TInput, TResult> evaluator, TResult failureValue)
            where TInput : class
        {
            return IsNull(o) ? failureValue : evaluator(o);
        }

        private static bool IsNull<T>(T o)
        {
            var mas = o as IEnumerable<Object>;
            if (mas != null) return mas.IsNullOrEmpty();
            return o == null;
        }

	}
}
